home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *
- * FILEMON - File Monitor for Windows 95
- *
- * By Mark Russinovich and Bryce Cogswell
- *
- * PROGRAM: filemon.c
- *
- * PURPOSE: Communicates with the filemon driver to display
- * file system activity information.
- *
- ******************************************************************************/
- #include <windows.h> // includes basic windows functionality
- #include <windowsx.h>
- #include <commctrl.h> // includes the common control header
- #include <stdio.h>
- #include <string.h>
- #include "resource.h"
- #include "../vxd/ioctlcmd.h"
-
-
- // Variables/definitions for the driver that performs the actual monitoring.
- #define VXD_FILE "\\\\.\\FILEVXD.VXD"
- #define VXD_NAME "FILEVXD"
- static HANDLE VxDHandle = INVALID_HANDLE_VALUE;
-
-
- // Buffer into which driver can copy statistics
- char Stats[ MAX_STORE ];
- // Current fraction of buffer filled
- DWORD StatsLen;
-
- // Application instance handle
- HINSTANCE hInst;
-
- // Misc globals
- HWND hWndList;
- BOOLEAN Capture = TRUE;
- BOOLEAN Autoscroll = TRUE;
- BOOLEAN Deleting = FALSE;
-
- // For info saving
- TCHAR szFileName[256];
- BOOLEAN FileChosen = FALSE;
-
- // General buffer for storing temporary strings
- static TCHAR msgbuf[ 257 ];
-
- // General cursor manipulation
- HCURSOR hSaveCursor;
- HCURSOR hHourGlass;
-
- // procs
- long APIENTRY MainWndProc( HWND, UINT, UINT, LONG );
- BOOL APIENTRY About( HWND, UINT, UINT, LONG );
-
- //functions
- BOOL InitApplication( HANDLE );
- HWND InitInstance( HANDLE, int );
- HWND CreateList( HWND );
- void UpdateStatistics( HWND hWnd, HWND hWndList, BOOL Clear );
- void SaveFile( HWND hDlg, HWND listbox, BOOLEAN SaveAs );
-
- /******************************************************************************
- *
- * FUNCTION: Abort:
- *
- * PURPOSE: Handles emergency exit conditions.
- *
- *****************************************************************************/
- void Abort( HWND hWnd, TCHAR * Msg )
- {
- MessageBox( hWnd, Msg, "filemon", MB_OK );
- PostQuitMessage( 1 );
- }
-
-
- /****************************************************************************
- *
- * FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
- *
- * PURPOSE: calls initialization function, processes message loop
- *
- ****************************************************************************/
- int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpCmdLine, int nCmdShow )
- {
- MSG msg;
- HWND hWnd;
-
- if ( ! InitApplication( hInstance ) )
- return FALSE;
-
- // initializations that apply to a specific instance
- if ( (hWnd = InitInstance( hInstance, nCmdShow )) == NULL )
- return FALSE;
-
-
- // acquire and dispatch messages until a WM_QUIT message is received.
- while ( GetMessage( &msg, NULL, 0, 0 ) ) {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
- return msg.wParam;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION: InitApplication(HANDLE)
- *
- * PURPOSE: Initializes window data and registers window class
- *
- ****************************************************************************/
- BOOL InitApplication( HANDLE hInstance )
- {
- WNDCLASS wc;
-
- // Fill in window class structure with parameters that describe the
- // main (statistics) window.
- wc.style = 0;
- wc.lpfnWndProc = (WNDPROC)MainWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon( hInstance, "ICON" );
- wc.hCursor = LoadCursor( NULL, IDC_ARROW );
- wc.hbrBackground = GetStockObject( LTGRAY_BRUSH );
- wc.lpszMenuName = "LISTMENU";
- wc.lpszClassName = "filemonClass";
- if ( ! RegisterClass( &wc ) )
- return FALSE;
-
- return TRUE;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION: InitInstance(HANDLE, int)
- *
- * PURPOSE: Saves instance handle and creates main window
- *
- ****************************************************************************/
- HWND InitInstance( HANDLE hInstance, int nCmdShow )
- {
- HWND hWndMain;
-
- hInst = hInstance;
-
- hWndMain = CreateWindow( "filemonClass", "Win95 File Monitor",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL, hInstance, NULL );
-
- // if window could not be created, return "failure"
- if ( ! hWndMain )
- return NULL;
-
- // make the window visible; update its client area; and return "success"
- ShowWindow( hWndMain, nCmdShow );
- UpdateWindow( hWndMain );
- return hWndMain;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
- *
- * PURPOSE: Processes messages for the statistics window.
- *
- ****************************************************************************/
- LONG APIENTRY MainWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam)
- {
- DWORD nb;
- TCHAR Path[ 256 ];
- PAINTSTRUCT Paint;
- HDC hDC;
-
- switch ( message ) {
-
- case WM_CREATE:
-
- // get hourglass cursor ready
- hHourGlass = LoadCursor( NULL, IDC_WAIT );
-
- // post hourglass icon
- SetCapture(hWnd);
- hSaveCursor = SetCursor(hHourGlass);
-
- // Create the ListBox within the main window
- hWndList = CreateList( hWnd );
- if ( hWndList == NULL )
- MessageBox( NULL, "List not created!", NULL, MB_OK );
-
- // open the handle to the device
- GetCurrentDirectory( sizeof Path, Path );
- wsprintf( Path+lstrlen(Path), "\\%s", VXD_FILE );
- // connect with VxD
- //VxDHandle = CreateFile( Path, 0, 0, NULL,
- VxDHandle = CreateFile( VXD_FILE, 0, 0, NULL,
- 0, FILE_FLAG_OVERLAPPED|
- FILE_FLAG_DELETE_ON_CLOSE,
- NULL );
- if ( VxDHandle == INVALID_HANDLE_VALUE ) {
- wsprintf( msgbuf, "%s is not loaded properly.", VXD_NAME );
- Abort( hWnd, msgbuf );
- return FALSE;
- }
-
- // Have driver zero information
- if ( ! DeviceIoControl( VxDHandle, FILEMON_zerostats,
- NULL, 0, NULL, 0, &nb, NULL ) )
- {
- Abort( hWnd, "Couldn't access device driver") ;
- return TRUE;
- }
-
- // Start up timer to periodically update screen
- SetTimer( hWnd, 1, 500/*ms*/, NULL );
-
- // Initialization done
- SetCursor( hSaveCursor );
- ReleaseCapture();
- return 0;
-
- case WM_NOTIFY:
- // Make sure its intended for us
- if ( wParam == ID_LIST ) {
- NM_LISTVIEW * pNm = (NM_LISTVIEW *)lParam;
- switch ( pNm->hdr.code ) {
-
- case LVN_BEGINLABELEDIT:
- // Don't allow editing of information
- return TRUE;
- }
- }
- return 0;
-
- case WM_COMMAND:
-
- switch ( LOWORD( wParam ) ) {
-
- // stats related commands to send to driver
- case IDM_CLEAR:
- // Have driver zero information
- if ( ! DeviceIoControl( VxDHandle, FILEMON_zerostats,
- NULL, 0, NULL, 0, &nb, NULL ) )
- {
- Abort( hWnd, "Couldn't access device driver");
- return TRUE;
- }
- // Update statistics windows
- UpdateStatistics( hWnd, hWndList, TRUE );
- return 0;
-
- case IDM_CAPTURE:
- // Read statistics from driver
- Capture = !Capture;
- CheckMenuItem( GetMenu(hWnd), IDM_CAPTURE,
- MF_BYCOMMAND|(Capture?MF_CHECKED:MF_UNCHECKED) );
- return 0;
-
- case IDM_AUTOSCROLL:
- Autoscroll = !Autoscroll;
- CheckMenuItem( GetMenu(hWnd), IDM_AUTOSCROLL,
- MF_BYCOMMAND|(Autoscroll?MF_CHECKED:MF_UNCHECKED) );
- return 0;
-
- case IDM_EXIT:
- // Close ourself
- SendMessage( hWnd, WM_CLOSE, 0, 0 );
- return 0;
-
- case IDM_SAVE:
- SaveFile( hWnd, hWndList, FALSE );
- return 0;
-
- case IDM_SAVEAS:
- SaveFile( hWnd, hWndList, TRUE );
- return 0;
-
- case IDM_ABOUT:
- // Show the names of the authors
- DialogBox( hInst, "AboutBox", hWnd, (DLGPROC)About );
- return 0;
-
- default:
- // Default behavior
- return DefWindowProc( hWnd, message, wParam, lParam );
- }
- break;
-
- case WM_TIMER:
- // Time to query the device driver for more data
- if ( Capture ) {
- for (;;) {
- // Have driver fill Stats buffer with information
- if ( ! DeviceIoControl( VxDHandle, FILEMON_getstats,
- NULL, 0, &Stats, sizeof Stats,
- &StatsLen, NULL ) )
- {
- Abort( hWnd, "Couldn't access device driver" );
- return TRUE;
- }
- if ( StatsLen == 0 )
- break;
- // Update statistics windows
- UpdateStatistics( hWnd, hWndList, FALSE );
- }
- }
- return 0;
-
- case WM_SIZE:
- // Move or resize the List
- MoveWindow( hWndList, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE );
- return 0;
-
- case WM_CLOSE:
- //PostQuitMessage( 0 );
- CloseHandle( VxDHandle );
- return DefWindowProc( hWnd, message, wParam, lParam );
-
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
-
- case WM_PAINT:
- if( Deleting ) {
- hDC = BeginPaint( hWnd, &Paint );
- EndPaint( hWnd, &Paint );
- return 1;
- }
- return DefWindowProc( hWnd, message, wParam, lParam );
-
- default:
- // Default behavior
- return DefWindowProc( hWnd, message, wParam, lParam );
- }
- return 0;
- }
-
-
- /******************************************************************************
- *
- * FUNCTION: Split
- *
- * PURPOSE: Split a delimited line into components
- *
- ******************************************************************************/
- int Split( char * line, char delimiter, char * items[] )
- {
- int cnt = 0;
-
- for (;;) {
- // Add prefix to list of components
- items[cnt++] = line;
-
- // Check for more components
- line = strchr( line, delimiter );
- if ( line == NULL )
- return cnt;
-
- // Terminate previous component and move to next
- *line++ = '\0';
- }
- }
-
-
- /******************************************************************************
- *
- * FUNCTION: ListAppend
- *
- * PURPOSE: Add a new line to List window
- *
- ******************************************************************************/
- BOOL List_Append( HWND hWndList, DWORD seq, char * line )
- {
- LV_ITEM lvI; // list view item structure
- int row;
- char * items[20];
- int itemcnt = 0;
-
- // Split line into columns
- itemcnt = Split( line, '\t', items );
- if ( itemcnt == 0 )
- return TRUE;
-
- // Determine row number for request
- if ( *items[0] ) {
- // Its a new request. Put at end.
- row = 0x7FFFFFFF;
- } else {
- // Its a status. Locate its associated request.
- lvI.mask = LVIF_PARAM;
- lvI.iSubItem = 0;
- for ( row = ListView_GetItemCount(hWndList) - 1; row >= 0; --row ) {
- lvI.iItem = row;
- if ( ListView_GetItem( hWndList, &lvI ) && (DWORD)lvI.lParam == seq )
- break;
- }
- if ( row == -1 )
- // No request associated with status.
- return TRUE;
- }
-
- // Sequence number if a new item
- if ( *items[0] ) {
- wsprintf( msgbuf, "%d", seq );
- lvI.mask = LVIF_TEXT | LVIF_PARAM;
- lvI.iItem = row;
- lvI.iSubItem = 0;
- lvI.pszText = msgbuf;
- lvI.cchTextMax = lstrlen( lvI.pszText ) + 1;
- lvI.lParam = seq;
- row = ListView_InsertItem( hWndList, &lvI );
- if ( row == -1 ) {
- wsprintf( msgbuf, "Error adding item %d to list view", seq );
- MessageBox( hWndList, msgbuf, "filemon Error", MB_OK );
- return FALSE;
- }
- }
-
- // Process Name
- if ( itemcnt>0 && *items[0] ) {
- OemToChar( items[0], msgbuf );
- ListView_SetItemText( hWndList, row, 1, msgbuf );
- }
-
- // Request Type
- if ( itemcnt>1 && *items[1] ) {
- OemToChar( items[1], msgbuf );
- ListView_SetItemText( hWndList, row, 2, msgbuf );
- }
-
- // Path
- if ( itemcnt>3 && *items[2] ) {
- OemToChar( items[2], msgbuf );
- ListView_SetItemText( hWndList, row, 3, msgbuf );
- }
-
- // Result
- if ( itemcnt>2 && *items[4] ) {
- OemToChar( items[4], msgbuf );
- ListView_SetItemText( hWndList, row, 4, msgbuf );
- }
-
- // Additional
- if ( itemcnt>3 && *items[3] ) {
- OemToChar( items[3], msgbuf );
- ListView_SetItemText( hWndList, row, 5, msgbuf );
- }
-
- return TRUE;
- }
-
-
- /******************************************************************************
- *
- * FUNCTION: UpdateStatistics
- *
- * PURPOSE: Clear the statistics window and refill it with the current
- * contents of the statistics buffer. Does not refresh the
- * buffer from the device driver.
- *
- ******************************************************************************/
- void UpdateStatistics( HWND hWnd, HWND hWndList, BOOL Clear )
- {
- PENTRY ptr;
- int totitems, i;
-
- // Just return if nothing to do
- if ( !Clear && StatsLen < sizeof(int)+2 )
- return;
-
- // Start with empty list
- if ( Clear ) {
- // post hourglass icon
- SetCapture(hWnd);
- hSaveCursor = SetCursor(hHourGlass);
-
- // Don't do this because ListView controls under Win95 have
- // a bug that makes it take sometimes several minutes to
- // delete all the items
- // ListView_DeleteAllItems( hWndList );
- totitems = ListView_GetItemCount( hWndList );
- Deleting = TRUE;
- for(i = 0; i < totitems; i++)
- ListView_DeleteItem( hWndList, 0 );
- Deleting = FALSE;
-
- // Delete done
- SetCursor( hSaveCursor );
- ReleaseCapture();
- }
-
-
- // Add all List items from Stats[] data
- for ( ptr = (void *)Stats; (char *)ptr < Stats+StatsLen; ) {
- // Add to list
- ULONG len = strlen(ptr->text);
- List_Append( hWndList, ptr->seq, ptr->text );
- ptr = (void *)(ptr->text + len + 1);
- }
-
- // Empty the buffer
- StatsLen = 0;
-
- // Scroll so newly added items are visible
- if ( Autoscroll )
- ListView_EnsureVisible( hWndList, ListView_GetItemCount(hWndList)-1, FALSE );
- }
-
-
- /****************************************************************************
- *
- * FUNCTION: CreateListView(HWND)
- *
- * PURPOSE: Creates the statistics list view window and initializes it
- *
- ****************************************************************************/
- HWND CreateList( HWND hWndParent )
- {
- HWND hWndList; // handle to list view window
- RECT rc; // rectangle for setting size of window
- LV_COLUMN lvC; // list view column structure
- DWORD j;
- static struct {
- TCHAR * Label; // title of column
- DWORD Width; // width of column in pixels
- DWORD Fmt;
- } column[] = {
- { "#" , 35 },
- { "Process" , 100 },
- { "Request" , 120 },
- { "Path" , 200 },
- { "Result" , 70 },
- { "Other" , 170 },
- };
-
- // Ensure that the common control DLL is loaded.
- InitCommonControls();
-
- // Get the size and position of the parent window.
- GetClientRect( hWndParent, &rc );
-
- // Create the list view window
- hWndList = CreateWindowEx( 0L, WC_LISTVIEW, "",
- WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT |
- WS_EX_CLIENTEDGE, // styles
- 0, 0, rc.right - rc.left, rc.bottom - rc.top,
- hWndParent, (HMENU)ID_LIST, hInst, NULL );
- if ( hWndList == NULL )
- return NULL;
-
- // Initialize columns
- lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
- lvC.fmt = LVCFMT_LEFT; // left-align column
-
- // Add the columns.
- for ( j = 0; j < sizeof column/sizeof column[0]; ++j ) {
- lvC.iSubItem = j;
- lvC.cx = column[j].Width;
- lvC.pszText = column[j].Label;
- if ( ListView_InsertColumn( hWndList, j, &lvC ) == -1 )
- return NULL;
- }
-
- return hWndList;
- }
-
-
- /****************************************************************************
- *
- * FUNCTION: SaveFile()
- *
- * PURPOSE: Lets the user go select a file.
- *
- ****************************************************************************/
- void SaveFile( HWND hWnd, HWND ListBox, BOOLEAN SaveAs )
- {
- OPENFILENAME SaveFileName;
- char szFile[256] = "", fieldtext[256], output[1024];
- FILE *hFile;
- int numitems;
- int row, subitem;
-
- if( SaveAs || !FileChosen ) {
- SaveFileName.lStructSize = sizeof (SaveFileName);
- SaveFileName.hwndOwner = hWnd;
- SaveFileName.hInstance = (HANDLE) hInst;
- SaveFileName.lpstrFilter = "File Data (*.FIL)\0*.FIL\0All (*.*)\0*.*\0";
- SaveFileName.lpstrCustomFilter = (LPTSTR)NULL;
- SaveFileName.nMaxCustFilter = 0L;
- SaveFileName.nFilterIndex = 1L;
- SaveFileName.lpstrFile = szFile;
- SaveFileName.nMaxFile = 256;
- SaveFileName.lpstrFileTitle = NULL;
- SaveFileName.nMaxFileTitle = 0;
- SaveFileName.lpstrInitialDir = NULL;
- SaveFileName.lpstrTitle = "Save File Info...";
- SaveFileName.nFileOffset = 0;
- SaveFileName.nFileExtension = 0;
- SaveFileName.lpstrDefExt = "*.fil";
- SaveFileName.lpfnHook = NULL;
- SaveFileName.Flags = OFN_LONGNAMES|OFN_HIDEREADONLY;
-
- if( !GetSaveFileName( &SaveFileName ))
- return;
- } else
- // open previous szFile
- strcpy( szFile, szFileName );
-
- // open the file
- hFile = fopen( szFile, "w" );
- if( !hFile ) {
- MessageBox( NULL, "Create File Failed.",
- "Save Error", MB_OK|MB_ICONSTOP );
- return;
- }
- // post hourglass icon
- SetCapture(hWnd);
- hSaveCursor = SetCursor(hHourGlass);
-
- numitems = ListView_GetItemCount(ListBox);
- for ( row = 0; row < numitems; row++ ) {
- output[0] = 0;
- for( subitem = 0; subitem < 6; subitem++ ) {
- fieldtext[0] = 0;
- ListView_GetItemText( ListBox, row, subitem, fieldtext, 256 );
- strcat( output, fieldtext );
- strcat( output, "\t" );
- }
- fprintf( hFile, "%s\n", output );
- }
- fclose( hFile );
- strcpy( szFileName, szFile );
- FileChosen = TRUE;
- SetCursor( hSaveCursor );
- ReleaseCapture();
- }
-
-
- /****************************************************************************
- *
- * FUNCTION: About
- *
- * PURPOSE: Processes messages for "About" dialog box
- *
- ****************************************************************************/
-
- BOOL APIENTRY About( HWND hDlg, UINT message, UINT wParam, LONG lParam )
- {
- switch ( message ) {
- case WM_INITDIALOG:
- return TRUE;
-
- case WM_COMMAND:
- if ( LOWORD( wParam ) == IDOK ) {
- EndDialog( hDlg, TRUE );
- return TRUE;
- }
- break;
- }
- return FALSE;
- }
-